<?php

/**
 * Framework_Message
 *
 * @author      Ian Szewczyk <roamzero@gmail.com>
 * @copyright   (c) 2007 Ian Szewczyk. All rights reserved.
 * @license     http://www.opensource.org/licenses/bsd-license.php
 * @package Framework
 * @filesource
 */


/**
 * Framework_Message
 *
 *
 * @author Ian Szewczyk <roamzero@gmail.com>
 * @package Framework
 */
class Framework_Message
{
	/**
	 * $to
	 *
	 * @access      private
	 * @var         mixed      $to		Either a user ID or peopletab login (username@domain.com)
	 */
	private $to;
	
	/**
	 * $from
	 *
	 * @access      private
	 * @var         Framework_Owner     $from		Framework_Owner object as sender
	 */
	private $from;
	
	/**
	 * $messageTitle
	 *
	 * @access      private
	 * @var         string      $messageTitle
	 */
	private $messageTitle;

	/**
	 * $message
	 *
	 * @access      private
	 * @var         string      $message
	 */
	private $message;

	/**
	 * $messageCategory
	 *
	 * @access      private
	 * @var         string      $messageCategory
	 */
	private $messageCategory;
	
	/**
	 * $recipient
	 *
	 * @access      private
	 * @var         Framework_User_Peopletab     $recipient
	 */
	private $recipient;

	/**
     * __construct
     *
	 * @access 		public
     * @param		Framework_Owner		$from		
     * @return 		void
     */
    public function __construct($from = null)
	{
		if (isset($from))
			$this->from = $from;
	}

	/**
     * setMessage
     *
	 * @access 		public
     * @param		string		$message
     * @return 		void
     */
	public function setMessage($message)
	{
		$this->message = $message;
	}

	/**
     * setFromUser
     *
	 * @access 		public
     * @param		object		$user		Instance of Framework_Owner
     * @return 		void
     */
	public function setFromUser($user)
	{
		$this->from = $user;
	}
	
	/**
     * setTitle
     *
	 * @access 		public
     * @param		string		$title
     * @return 		void
     */
	public function setTitle($title)
	{
		$this->messageTitle = $title;
	}
	
	/**
     * setMessageCategory
     *
	 * @access 		public
     * @param		string		$category
     * @return 		void
     */
	public function setMessageCategory($category)
	{
		$this->messageCategory = $category;
	}
	
	/**
     * setRecipient
     *
	 * @access 		public
     * @param		object		$user		Instance of Framework_User_Peopletab
     * @return 		void
     */
	public function setRecipient($user)
	{
		$this->recipient = $user;
	}
	
	/**
     * setTo
     *
	 * @access 		public
     * @param		mixed		$to		User id or peopletab login (username@site.com)
     * @return 		void
     */
	public function setTo($to)
	{
		$this->to = $to;
	}

	/**
     * send
     *
	 * @access 		public
     * @return 		mixed 		void, PEAR_Error on failure
     */
	public function send()
	{
		if(!isset($this->message) || !isset($this->to)) {
			return PEAR::raiseError('Object Properties Not Set');
		} else {
			
			// sanitize message and parse BBcode
			
				
			if (preg_match("/^[0-9]+$/", $this->to)) {
				$this->recipient = new Framework_User_Peopletab($this->to,null);
			} else {
				
				$this->recipient = new Framework_User_Peopletab(null,$this->to);

			}

			if($this->recipient->isValid) {
				if($this->recipient->siteDomain == $_SERVER['HTTP_HOST']){
					$result = $this->save();
				} else {
					$result = $this->remoteSend();
					// add to keep a 'sent' record
					if (!PEAR::isError($result)) {
						$this->save(1,0);
					}
				}
				return $result;
			} else {
				return PEAR::raiseError('Could Not Look Up Recipient');
			}


		}
	}

	/**
     * remoteSend
     *
	 * @access 		public
     * @return 		mixed 		void, PEAR_Error on failure
     */
	public function remoteSend()
	{
		if (is_a($this->from,'Framework_Owner')) {
			require_once "HTTP/Request.php";
			$req = new HTTP_Request('http://'.$this->recipient->siteDomain.'/'.$this->recipient->userName.'/User/RemoteMessage');
			$req->setMethod(HTTP_REQUEST_METHOD_POST);
	
			// Generate Signature
			require_once 'Crypt/RSA.php';
			require_once 'Crypt/RSA/Key.php';
	
			$rsa_obj = new Crypt_RSA(array(
				'private_key' => Crypt_RSA_Key::fromString($this->from->privateKey),
			));
	
			$time = time();
	
			$signature = $rsa_obj->createSign($time.$this->recipient->userName.$this->recipient->domain.$this->message);
			if ($rsa_obj->isError()){
				$error = $rsa_obj->getLastError();
				$errors[] = $error->getMessage();
			}
	
			$req->addPostData('time',$time);
			$req->addPostData('from',$this->from->userName.'@'.$this->from->siteDomain);
			$req->addPostData('signature', $signature);
			$req->addPostData('messageTitle', $this->messageTitle);
			$req->addPostData('message', $this->message);
	
			$result = $req->sendRequest();
			if (PEAR::isError($result)) {
				return PEAR::raiseError('Network Error: Could not contact site to complete request: '.$result->getMessage());
			} else {
				$xml = $req->getResponseBody();
				$xml = @simplexml_load_string($xml);
				if($xml) {
					if ($xml->header->type == 'error'){
						return PEAR::raiseError('Error Sending Message Remotely: '.$xml->message->errorMessage.' Local:'.$time.$this->recipient->remoteUserName.$this->recipient->domain.$this->message);
	
					} elseif($xml->header->type == 'RemoteMessage') {
						return true;
					} else {
						return PEAR::raiseError('Invalid Response Header');
					}
				} else {
					// TEST THIS!!
					return PEAR::raiseError('SimpleXML: Invalid XML ');
				}
			}
		} else {
			return PEAR::raiseError('Cannot forward remotely, sender is not an owner');
		}

	}

	/**
     * save
     *
	 * @access 		public
     * @param		integer		$senderStatus		
     * @param		integer		$recieverStatus		
     * @param		integer		$readStatus			
     * @return 		mixed 		boolean true, PEAR_Error on failure
     */
	public function save($senderStatus = 1, $recieverStatus = 1, $readStatus = 0){
		 if (!$this->messageCategory) {
		 	 if(is_a($this->from,'Framework_Owner'))
			 	$recipientStatus = $this->from->friendStatus($this->recipient);
			 elseif (is_a($this->recipient,'Framework_Owner')) 
			 	$recipientStatus = $this->recipient->friendStatus($this->from);
			 else 
			 	$recipientStatus = -1;
			 
			 switch (true) {
			 	case $recipientStatus == USER_FRIENDS_WITH_OWNER :
			 		$this->messageCategory = 'friends';		
			 	break;
			 	
			 	case $recipientStatus == USER_WATCHING_OWNER :
			 		$this->messageCategory = 'watching';		
			 	break;
			 	
			 	case $recipientStatus == USER_WATCHED_BY_OWNER :
			 		$this->messageCategory = 'watchedBy';		
			 	break;
			 	
			 	default:
			 		$this->messageCategory = 'other';	
			 	break;
			 }
		 }

		 $messageDB = Framework_DB::dbFactory('Message');
		 
		 $privateMsgTable = $messageDB->getTable('PrivateMsg');
		 
	     $privateMsgTable->idMsgCategory = $messageDB->select(array('sqlKey' => 'getMessageCategory', 'params' => array($this->messageCategory)));
		 $privateMsgTable->idSiteUserRec =  $this->recipient->idSiteUser;
		 $privateMsgTable->idSiteUserSen = $this->from->idSiteUser;
		 $privateMsgTable->readStatus = $readStatus;
		 $privateMsgTable->recieverStatus = $recieverStatus;
		 $privateMsgTable->senderStatus = $senderStatus;
		 $privateMsgTable->timeSent = time();
		 $privateMsgTable->messageTitle = $this->messageTitle;
		 $privateMsgTable->message = $this->message;
		 
		 $result = $privateMsgTable->save();
		 
		 
		 
		 return $result;
	}

}

?>